home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ada / gwuada_9.zip / PREDEF2.C < prev    next >
C/C++ Source or Header  |  1993-07-27  |  15KB  |  463 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9. /*    +---------------------------------------------------+
  10.       |                                                   |
  11.       |          I N T E R P     P R E D E F S            |
  12.       |            Part 2: CALENDAR Procedure             |
  13.       |                  (C Version)                      |
  14.       |                                                   |
  15.       |   Adapted From Low Level SETL version written by  |
  16.       |                                                   |
  17.       |                  Monte Zweben                     |
  18.       |               Philippe Kruchten                   |
  19.       |               Jean-Pierre Rosen                   |
  20.       |                                                   |
  21.       |    Original High Level SETL version written by    |
  22.       |                                                   |
  23.       |                   Clint Goss                      |
  24.       |               Tracey M. Siesser                   |
  25.       |               Bernard D. Banner                   |
  26.       |               Stephen C. Bryant                   |
  27.       |                  Gerry Fisher                     |
  28.       |                                                   |
  29.       |              C version written by                 |
  30.       |                                                   |
  31.       |               Robert B. K. Dewar                  |
  32.       |                                                   |
  33.       +---------------------------------------------------+
  34. */
  35.  
  36. /* This module contains the implementation of the CALENDAR package */
  37.  
  38. #include "ipredef.h"
  39. #include "time.h"
  40. #include "intbp.h"
  41. #include "intcp.h"
  42. #include "predefp.h"
  43. #include <conio.h>
  44.  
  45. /* Structure corresponding to Ada record TIME */
  46.  
  47. struct time_record {
  48.     int     year_val;
  49.     int     month_val;
  50.     int     day_val;
  51.     long    secs_val;
  52. };
  53.  
  54. static long days_in(int, int, int);
  55. static void ymd_of(long days, int *, int *, int *);
  56. static void get_time(struct time_record *);
  57.  
  58. /*  Macros for treating pointer as pointer to time_record, and length in
  59.  *  words of time record(used when creating an object of this type.
  60.  */
  61.  
  62. #define TIME_RECORD(ptr)    ((struct time_record *)(ptr))
  63. #define WORDS_TIME_RECORD   (sizeof(struct time_record) / sizeof (int))
  64.  
  65. /*  Constants for CALENDAR */
  66.  
  67. #define ONE_DAY   86400000L       /* 24 * 60 * 60 * 1000 (milliseconds) */
  68.  
  69. static int days_before_month[] = {
  70.     0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
  71. };
  72.  
  73. static int days_in_month[] = {
  74.     0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  75. };
  76.  
  77.  
  78. /* CALENDAR */
  79.  
  80. /* Control passes to the CALENDAR procedure from PREDEF when it encounters an
  81.  * operation code value corresponding to a predefined calendar operation.
  82. */
  83.  
  84. void calendar()                                               /*;calendar*/
  85. {
  86.     switch(operation) {
  87.  
  88.         /* function CLOCK return TIME; */
  89.  
  90.     case P_CLOCK:
  91.         {
  92.             int    bse, off;
  93.             int    *ptr;
  94.  
  95.             create(WORDS_TIME_RECORD, &bse, &off, &ptr);
  96.             get_time((struct time_record  *) ptr);
  97.             TOSM(1) = bse;
  98.             TOS = off;
  99.             break;
  100.         }
  101.  
  102.  
  103.         /* function YEAR(DATE : in TIME) return YEAR_NUMBER; */
  104.  
  105.     case P_YEAR:
  106.         TOSM(2) = TIME_RECORD(get_argument_ptr(0)) -> year_val;
  107.         break;
  108.  
  109.         /* function MONTH(DATE : in TIME) return MONTH_NUMBER; */
  110.  
  111.     case P_MONTH:
  112.         TOSM(2) = TIME_RECORD(get_argument_ptr(0)) -> month_val;
  113.         break;
  114.  
  115.         /* function DAY(DATE : in TIME) return DAY_NUMBER; */
  116.  
  117.     case P_DAY:
  118.         TOSM(2) = TIME_RECORD(get_argument_ptr(0)) -> day_val;
  119.         break;
  120.  
  121.         /* function SECONDS(DATE : in TIME) return DURATION; */
  122.  
  123.     case P_SECONDS:
  124.         {
  125.             int  bse,off;
  126.             long secs,tmp;
  127.  
  128.             /*TOSM(2) = TIME_RECORD(get_argument_ptr(0)) -> secs_val;*/
  129.             /* direct code needed since TOSML macro wrong */
  130.             /* pop arguments, store long and restore args */
  131.             secs = TIME_RECORD(get_argument_ptr(0)) -> secs_val;
  132.  
  133. /*WAS AVL secs = TIME_RECORD(get_argument_ptr(0)) -> secs_val;
  134. */
  135.             POP_ADDR(bse,off);
  136.             POPL(tmp); /* pop current value */
  137.             PUSHL(secs); /* push correct value */
  138.             PUSH_ADDR(bse,off); /* restore arg on stack */
  139.         }
  140.         break;
  141.  
  142.         /* procedure SPLIT(DATE      : in  TIME;          */
  143.         /*                 YEAR      : out YEAR_NUMBER;   */
  144.         /*                 MONTH     : out MONTH_NUMBER;  */
  145.         /*                 DAY       : out DAY_NUMBER;    */
  146.         /*                 SECONDS   : out DURATION);     */
  147.  
  148.     case P_SPLIT:
  149.         {
  150.             struct time_record *time_ptr;
  151.             long *p;
  152.  
  153.             time_ptr = TIME_RECORD(get_argument_ptr(0));
  154.  
  155.             *get_argument_ptr(2)  = time_ptr -> year_val;
  156.             *get_argument_ptr(6)  = time_ptr -> month_val;
  157.             *get_argument_ptr(10) = time_ptr -> day_val;
  158.             p = (long *) get_argument_ptr(14) ;
  159.             *p = time_ptr -> secs_val;
  160.             break;
  161.         }
  162.  
  163.         /* function TIME_OF(YEAR     : YEAR_NUMBER;                   */
  164.         /*                  MONTH    : MONTH_NUMBER;                  */
  165.         /*                  DAY      : DAY_NUMBER;                    */
  166.         /*                  SECONDS  : DURATION := 0.0) return TIME;  */
  167.  
  168.     case P_TIME_OF:
  169.         {
  170.             int    year, month, day;
  171.             long   secs;
  172.             long   days;
  173.             int    bse, off;
  174.             struct time_record *time_ptr;
  175.  
  176.             year  = get_argument_value(0);
  177.             month = get_argument_value(2);
  178.             day   = get_argument_value(4);
  179.             secs  = get_long_argument_value(6);
  180.  
  181.             if ((year % 4) == 0 && month == 2) {
  182.                 if (day > 29) { /* check leap year */
  183.                     raise(TIME_ERROR, "Day too large");
  184.                     return;
  185.                 }
  186.             }
  187.             else if (day > days_in_month[month]) {
  188.                 raise(TIME_ERROR, "Day too large");
  189.                 return;
  190.             }
  191.             if (secs >= ONE_DAY) {
  192.                 secs -= ONE_DAY;
  193.                 days = days_in(year, month, day + 1);
  194.                 ymd_of(days, &year, &month, &day);
  195.                 if (year < 1901 || year > 2099) {
  196.                     raise(TIME_ERROR, "Year out of range");
  197.                     return;
  198.                 }
  199.             }
  200.             create(WORDS_TIME_RECORD, &bse, &off,(int **)(&time_ptr));
  201.             time_ptr -> year_val  = year;
  202.             time_ptr -> month_val = month;
  203.             time_ptr -> day_val   = day;
  204.             time_ptr -> secs_val  = secs;
  205.             TOSM(9) = bse;
  206.             TOSM(8) = off;
  207.             break;
  208.         }
  209.  
  210.         /* function "+"(LEFT : TIME;     RIGHT : DURATION)  return TIME; */
  211.         /* function "+"(LEFT : DURATION; RIGHT : TIME)      return TIME; */
  212.         /* function "-"(LEFT : TIME;     RIGHT : DURATION)  return TIME; */
  213.  
  214.     case P_ADD_TIME_DUR:
  215.     case P_ADD_DUR_TIME:
  216.     case P_SUB_TIME_DUR:
  217.         {
  218.             struct time_record *time_ptr;
  219.             long   dur;
  220.             int    year, month, day;
  221.             long   secs,days;
  222.             int    add_day;
  223.             int    bse, off;
  224.  
  225.             if (operation == P_ADD_TIME_DUR) {
  226.                 time_ptr = TIME_RECORD(get_argument_ptr(0));
  227.                 dur = get_long_argument_value(2);
  228.             }
  229.             else if (operation == P_ADD_DUR_TIME) {
  230.                 dur = get_long_argument_value(0);
  231.                 time_ptr = TIME_RECORD(get_argument_ptr(2));
  232.             }
  233.             else { /* operation == P_SUB_TIME_DUR */
  234.                 time_ptr = TIME_RECORD(get_argument_p